﻿using System;
using System.Linq;
using System.Reflection;

namespace LuceneApiServerLib.Core
{
    public class ApiAction
    {
        /// <summary>
        ///     参数值
        /// </summary>
        [ThreadStatic] private static object[] parameters;

        /// <summary>
        ///     Api行为的方法成员调用委托
        /// </summary>
        private readonly Func<object, object[], object> methodInvoker;

        /// <summary>
        ///     Api行为
        /// </summary>
        /// <param name="method">方法信息</param>
        /// <exception cref="ArgumentException"></exception>
        public ApiAction(MethodInfo method)
        {
            Method = method;
            methodInvoker = MethodReflection.CreateInvoker(method);

            DeclaringService = method.DeclaringType;
            ReturnType = method.ReturnType;
            IsVoidReturn = method.ReturnType == typeof (void);
            ParameterInfos = method.GetParameters();
            ParameterTypes = ParameterInfos.Select(item => item.ParameterType).ToArray();
        }

        /// <summary>
        ///     获取Api行为的Api名称
        /// </summary>
        public string ApiName { get; protected set; }

        /// <summary>
        ///     获取Api行为的方法成员返回类型是否为void
        /// </summary>
        public bool IsVoidReturn { get; private set; }

        /// <summary>
        ///     Api行为的方法成员返回类型
        /// </summary>
        public Type ReturnType { get; private set; }

        /// <summary>
        ///     获取Api行为的参数信息
        /// </summary>
        public ParameterInfo[] ParameterInfos { get; private set; }

        /// <summary>
        ///     获取Api行为的方法成员参数类型
        /// </summary>
        public Type[] ParameterTypes { get; private set; }

        /// <summary>
        ///     获取Api行为的参数值
        /// </summary>
        public object[] ParameterValues
        {
            get { return parameters; }
            internal set { parameters = value; }
        }

        /// <summary>
        ///     获取方法成员信息
        /// </summary>
        public MethodInfo Method { get; private set; }

        /// <summary>
        ///     获取声明该成员的服务类型
        /// </summary>
        public Type DeclaringService { get; protected set; }

        /// <summary>
        ///     获取Api行为或Api行为的声明类型是否声明了特性
        /// </summary>
        /// <param name="type">特性类型</param>
        /// <param name="inherit">是否继承</param>
        /// <returns></returns>
        public bool IsDefined(Type type, bool inherit)
        {
            return Method.IsDefined(type, inherit) || DeclaringService.IsDefined(type, inherit);
        }

        /// <summary>
        ///     执行Api行为
        /// </summary>
        /// <param name="service">服务实例</param>
        /// <param name="parameters">参数实例</param>
        /// <returns></returns>
        public object Execute(object service, params object[] parameters)
        {
            return methodInvoker.Invoke(service, parameters);
        }
    }
}